package com.zyf.project.binaryproto.encoder.impl;

import com.zyf.project.binaryproto.converter.DynamicValueConverter;
import com.zyf.project.binaryproto.converter.impl.AbstractNumberEncodingConverter;
import com.zyf.project.binaryproto.specification.BinarySliceSpecification;
import com.zyf.project.binaryproto.specification.FieldSpecification;
import org.jetbrains.annotations.NotNull;
import utils.binary.BytesSlices;
import utils.binary.impl.SingleBytesSliceArray;
import utils.binary.io.BytesInputStream;
import utils.binary.io.BytesOutputBuffer;
import utils.io.NumberMask;

import java.lang.reflect.Method;

/**
 * @author Zhou Yifan
 */
public class DynamicFieldEncoder extends AbstractFieldEncoder {

    private DynamicValueConverter valueConverter;

    private NumberMask numberMask;

    public DynamicFieldEncoder(BinarySliceSpecification sliceSpec, FieldSpecification fieldSpec, Method reader,
                               DynamicValueConverter valueConverter) {
        super(sliceSpec, fieldSpec, reader);
        this.valueConverter = valueConverter;
        if (valueConverter instanceof AbstractNumberEncodingConverter) {
            numberMask = ((AbstractNumberEncodingConverter) valueConverter).getNumberMask();
        }
    }

    /**
     * 将数据序列化到指定缓存中
     *
     * @param dataContract 数据
     * @param buffer       指定缓存 {@link BytesOutputBuffer}
     * @return 写入的字节数
     */
    @Override
    public int encode(Object dataContract, BytesOutputBuffer buffer) {
        int size = 0;
        Object value = readValue(dataContract);
        size += valueConverter.encode(value, buffer);
        return size;
    }

    /**
     * 将 BytesInputStream 反序列化成数据片
     *
     * @param bytesInputStream {@link BytesInputStream}
     * @return {@link BytesSlices}
     */
    @Override
    public BytesSlices decode(BytesInputStream bytesInputStream) {
        if (numberMask != null) {
            return SingleBytesSliceArray.resolveNumber(numberMask, bytesInputStream);
        }else {
            return SingleBytesSliceArray.resolveDynamic(bytesInputStream);
        }
    }

    /**
     * 字段解码
     *
     * @param fieldBytes 一组相关联的数据片段 {@link BytesSlices}
     * @return 对象 {@link Object}
     */
    @Override
    public Object decodeField(BytesSlices fieldBytes) {
        // 非数组的字段，最多只有一个数据片段；
        if (null == fieldBytes || fieldBytes.getCount() == 0) {
            return valueConverter.getDefaultValue();
        }
        return valueConverter.decode(fieldBytes.getDataSlice(0));
    }
}
